<template>
  <div class="chat-container">
    <el-card class="chat-card">
      <div class="card-header">
        <h3>AI智能问答</h3>
        <el-button 
          type="danger" 
          size="small" 
          @click="clearHistory" 
          class="clear-button"
          :disabled="chatHistory.length === 0">
          清空历史
        </el-button>
      </div>
      
      <!-- 聊天记录区域 -->
      <div class="chat-history" ref="chatHistory">
        <div v-for="(msg, index) in chatHistory" :key="index" :class="['message', msg.role]">
          <div class="avatar">
            <img :src="msg.role === 'user' ? '/user-miffy.png' : '/miffy.png'" :alt="msg.role === 'user' ? '用户' : 'AI'" />
          </div>
          <div class="message-bubble">
            <div class="message-header">{{ msg.role === 'user' ? '' : 'AI助手' }}</div>
            <div class="message-content" v-html="formatMessage(msg.content)"></div>
          </div>
        </div>
        
        <!-- 流式响应正在加载时显示 -->
        <div v-if="isLoading" class="message ai">
          <div class="avatar">
            <img src="/miffy.png" alt="AI" />
          </div>
          <div class="message-bubble">
            <div class="message-header">AI助手</div>
            <div class="message-content" v-html="formatMessage(currentResponse)"></div>
            <div class="typing-indicator">
              <span></span>
              <span></span>
              <span></span>
            </div>
          </div>
        </div>
      </div>

      <!-- 输入区域 -->
      <div class="input-area">
        <el-input
          v-model="userMessage"
          type="textarea"
          :rows="3"
          placeholder="请输入您的问题..."
          @keyup.ctrl.enter="handleSendMessage"
          :disabled="isLoading"
        ></el-input>
        <el-button 
          type="primary" 
          @click="handleSendMessage" 
          :disabled="!userMessage.trim() || isLoading"
          :loading="isLoading"
          class="send-button"
        >
          发送
        </el-button>
      </div>
    </el-card>
  </div>
</template>

<script>
import api from '../api/index.js'

export default {
  name: 'ChatBox',
  data() {
    return {
      userMessage: '',
      chatHistory: [],
      currentResponse: '',
      isLoading: false
    }
  },
  methods: {
    async handleSendMessage() {
      if (!this.userMessage.trim() || this.isLoading) return;
      
      // 添加用户消息到历史
      const userMessage = {
        role: 'user',
        content: this.userMessage
      };
      this.chatHistory.push(userMessage);
      
      const userQuery = this.userMessage;
      this.userMessage = ''; // 清空输入框
      this.isLoading = true;
      this.currentResponse = '';
      
      try {
        // 构建请求体，包含历史消息
        const chatRequest = {
          prompt: userQuery,
          messages: this.chatHistory.map(msg => ({
            role: msg.role === 'user' ? 'user' : 'assistant',
            content: msg.content
          })),
          useContext: true
        };
        
        // 使用api接口发送流式请求
        const response = await api.streamChat(chatRequest);
        
        const reader = response.body.getReader();
        const decoder = new TextDecoder();
        
        // 读取流式响应
        let reading = true;
        while (reading) {
          const { done, value } = await reader.read();
          if (done) {
            reading = false;
            break;
          }
          
          // 解码当前块
          const chunk = decoder.decode(value, { stream: true });
          this.currentResponse += chunk;
          this.scrollToBottom();
        }
        
        // 流式响应完成后，添加到历史
        this.chatHistory.push({
          role: 'ai',
          content: this.currentResponse
        });
        this.currentResponse = '';
      } catch (error) {
        console.error('聊天错误:', error);
        // 显示错误信息
        this.chatHistory.push({
          role: 'ai',
          content: `发生错误: ${error.message}`
        });
      } finally {
        this.isLoading = false;
        this.$nextTick(this.scrollToBottom);
      }
    },
    
    formatMessage(text) {
      if (!text) return '';
      
      // 处理Markdown格式
      let formatted = text
        // 代码块
        .replace(/```([\s\S]*?)```/g, '<pre class="code-block">$1</pre>')
        // 行内代码
        .replace(/`([^`]+)`/g, '<code>$1</code>')
        // 粗体
        .replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>')
        .replace(/__([^_]+)__/g, '<strong>$1</strong>')
        // 斜体
        .replace(/\*([^*]+)\*/g, '<em>$1</em>')
        .replace(/_([^_]+)_/g, '<em>$1</em>')
        // 标题
        .replace(/^# (.+)$/gm, '<h1>$1</h1>')
        .replace(/^## (.+)$/gm, '<h2>$1</h2>')
        .replace(/^### (.+)$/gm, '<h3>$1</h3>')
        // 列表
        .replace(/^- (.+)$/gm, '<li>$1</li>')
        .replace(/^\d+\. (.+)$/gm, '<li>$1</li>')
        // 引用
        .replace(/^> (.+)$/gm, '<blockquote>$1</blockquote>')
        // 链接
        .replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2" target="_blank">$1</a>')
        // 换行
        .replace(/\n/g, '<br>');
      
      return formatted;
    },
    
    scrollToBottom() {
      if (this.$refs.chatHistory) {
        this.$refs.chatHistory.scrollTop = this.$refs.chatHistory.scrollHeight;
      }
    },
    clearHistory() {
      this.chatHistory = [];
      this.currentResponse = '';
      this.userMessage = '';
      this.isLoading = false;
      this.$nextTick(this.scrollToBottom);
    }
  },
  mounted() {
    // 初始化时滚动到底部
    this.scrollToBottom();
  }
}
</script>

<style scoped>
.chat-container {
  width: 100%;
  max-width: 900px;
  margin: 0 auto;
}

.chat-card {
  width: 100%;
  border-radius: 12px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.08);
  border: none;
  background-color: #ffffff;
  overflow: hidden;
}

.card-header {
  margin-bottom: 24px;
  text-align: center;
  color: #303133;
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
}

.card-header h3 {
  font-size: 24px;
  font-weight: 600;
  margin: 0;
  color: #333;
}

.clear-button {
  position: absolute;
  right: 0;
  top: 0;
}

.chat-history {
  height: 450px;
  overflow-y: auto;
  padding: 20px;
  margin-bottom: 24px;
  border-radius: 8px;
  background-color: #f9f9fc;
}

.message {
  display: flex;
  margin-bottom: 24px;
  align-items: flex-start;
}

.avatar {
  width: 40px;
  height: 40px;
  border-radius: 4px;
  margin-right: 12px;
  overflow: hidden;
  flex-shrink: 0;
  background-color: #f0f0f0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.message.user {
  flex-direction: row-reverse;
}

.message.user .avatar {
  margin-right: 0;
  margin-left: 12px;
}

.message-bubble {
  background-color: #fff;
  padding: 12px 16px;
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
  max-width: calc(100% - 70px);
}

.message.user .message-bubble {
  background-color: #e1f3fb;
  border: 1px solid #c6e6f5;
  border-top-right-radius: 4px;
}

.message.ai .message-bubble {
  background-color: #ffffff;
  border: 1px solid #ebeef5;
  border-top-left-radius: 4px;
}

.message-header {
  font-weight: 600;
  margin-bottom: 6px;
  font-size: 15px;
  color: #333;
}

.message-content {
  line-height: 1.6;
  color: #444;
  font-size: 15px;
}

.message-content :deep(pre.code-block) {
  background-color: #f5f5f5;
  padding: 12px;
  border-radius: 4px;
  margin: 8px 0;
  overflow-x: auto;
  font-family: 'SFMono-Regular', Consolas, monospace;
}

.message-content :deep(code) {
  background-color: #f0f0f0;
  padding: 2px 4px;
  border-radius: 3px;
  font-family: 'SFMono-Regular', Consolas, monospace;
}

.message-content :deep(blockquote) {
  border-left: 4px solid #ddd;
  padding-left: 16px;
  margin: 8px 0;
  color: #666;
}

.message-content :deep(h1) {
  font-size: 24px;
  margin: 16px 0 8px 0;
  font-weight: 600;
}

.message-content :deep(h2) {
  font-size: 20px;
  margin: 14px 0 8px 0;
  font-weight: 600;
}

.message-content :deep(h3) {
  font-size: 18px;
  margin: 12px 0 8px 0;
  font-weight: 600;
}

.message-content :deep(li) {
  margin: 4px 0 4px 20px;
  display: list-item;
  list-style: initial;
}

.input-area {
  display: flex;
  align-items: flex-end;
  padding: 0 16px 16px;
}

.input-area .el-textarea {
  margin-right: 16px;
  flex: 1;
}

.input-area .el-textarea :deep(.el-textarea__inner) {
  border-radius: 8px;
  padding: 12px 16px;
  border-color: #dcdfe6;
  transition: all 0.3s;
  resize: none;
}

.input-area .el-textarea :deep(.el-textarea__inner:focus) {
  border-color: #409eff;
  box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
}

.send-button {
  height: 48px;
  border-radius: 8px;
  padding: 0 24px;
  font-size: 16px;
  transition: all 0.3s;
}

.typing-indicator {
  display: flex;
  margin-top: 8px;
}

.typing-indicator span {
  height: 8px;
  width: 8px;
  background-color: #409eff;
  border-radius: 50%;
  display: inline-block;
  margin-right: 4px;
  animation: typing 1.5s infinite;
  opacity: 0.6;
}

.typing-indicator span:nth-child(2) {
  animation-delay: 0.2s;
}

.typing-indicator span:nth-child(3) {
  animation-delay: 0.4s;
}

@keyframes typing {
  0% { transform: translateY(0); }
  50% { transform: translateY(-5px); }
  100% { transform: translateY(0); }
}
</style> 